package cn.edu.jju.stepcounter2.service;

import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.util.Log;

import org.xutils.common.util.KeyValue;
import org.xutils.db.sqlite.WhereBuilder;
import org.xutils.ex.DbException;
import org.xutils.x;

import cn.edu.jju.stepcounter2.SCApp;
import cn.edu.jju.stepcounter2.bean.DayData;
import cn.edu.jju.stepcounter2.utils.SPUtils;

import static android.util.Log.i;

public class StepCountService extends Service implements SensorEventListener {

    private SensorManager sensorManager;
    private Sensor sensor;
    private int new_step;
    private int old_step;
    private double oldTime;
    private double currentTime;
    private static double energy;
    private int step;
    private float height;
    private DayData dayData;
    private float weight;
    private float speedAver;
    private int age;
    private float ratio;

    public StepCountService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        String date = (String) SPUtils.get(getApplicationContext(), "date", "1");
        height = Float.parseFloat((String) SPUtils.get(getApplicationContext(), "height", "1.72")) / 100;
        weight = Float.parseFloat((String) SPUtils.get(getApplicationContext(), "weight", "60"));
        speedAver = Float.parseFloat((String) SPUtils.get(getApplicationContext(), "speed", "1.25"));
        age = Integer.parseInt((String) SPUtils.get(getApplicationContext(), "age", "22"));
        setRatio();
        try {
            dayData = x.getDb(SCApp.daoConfig).selector(DayData.class)
                    .where("date", "=", date).findFirst();
            i("@@@", "onCreateStepConSer" + x.getDb(SCApp.daoConfig).selector(DayData.class)
                    .where("date", "=", date).findAll().size());
            String stepStr = dayData.getSteps();
            step = Integer.parseInt(stepStr);
            String calConsume = dayData.getCalConsume();
            energy = Double.parseDouble(calConsume);
        } catch (DbException e) {
            e.printStackTrace();
        }
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
        sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);

    }

    private void setRatio() {
        if (age >= 0 && age <= 15) {
            ratio = (float) 1.1;
        }
        if (age > 15 && age <= 25) {
            ratio = (float) 1.0;
        }
        if (age > 25 && age <= 35) {
            ratio = (float) 0.87;
        }
        if (age > 35 && age <= 40) {
            ratio = (float) 0.83;
        }
        if (age > 40 && age <= 45) {
            ratio = (float) 0.78;
        }
        if (age > 45 && age <= 50) {
            ratio = (float) 0.75;
        }
        if (age > 50 && age <= 55) {
            ratio = (float) 0.71;
        }
        if (age > 55 && age <= 60) {
            ratio = (float) 0.68;
        }
        if (age > 60 && age <= 70) {
            ratio = (float) 0.65;
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        sensorManager.unregisterListener(this, sensor);
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        String date = (String) SPUtils.get(getApplicationContext(), "date", "1");
        dayData.setDate(date);

        new_step = (int) sensorEvent.values[0];


        currentTime = System.currentTimeMillis() / 1000.0;
        if (old_step == 0 && oldTime == 0) {
            old_step = new_step;
            oldTime = currentTime;
        }

        getEnergy();
        Intent intent = new Intent("update");
        sendBroadcast(intent);
        old_step = new_step;
        oldTime = currentTime;


    }

    private void getEnergy() {
        int steps = new_step - old_step;
        float stepLength = (float) (height * 0.45);
        double times = currentTime - oldTime;
        double speed = stepLength * steps / times;
        if (times >= 5) {
            speed = speedAver;
        }
        if (speed < 2.777) {

            speed = ((int) (speed * 1000)) / 1000.0;
            speedAver = (float) ((speedAver + speed) / 2);
            SPUtils.put(this, "speed", String.valueOf(speedAver));
            double new_energy = (0.36063 * speed * speed - 0.78862 * speed + 0.9852) * stepLength * steps * weight * ratio;
//            i("@@@@@@@",  speed+"---"+stepLength+"---"+weight+"---"+steps+"---"+ratio+"---"+times);
            try {
                energy = Double.parseDouble(x.getDb(SCApp.daoConfig).selector(DayData.class).where("date", "=", dayData.getDate()).findFirst().getCalConsume());
            } catch (DbException e) {
                e.printStackTrace();
            }
            energy += new_energy;
            try {
                step = Integer.parseInt(x.getDb(SCApp.daoConfig).selector(DayData.class).where("date", "=", dayData.getDate()).findFirst().getSteps());
            } catch (DbException e) {
                e.printStackTrace();
            }
            step += steps;

            dayData.setSteps(String.valueOf(step));
//            i("@@@", "getEnergy" + String.valueOf(step));
            dayData.setCalConsume(String.valueOf(energy));
            try {
//            i("@@@", "DataSizeA" + x.getDb(SCApp.daoConfig).selector(DayData.class).findAll().size());
                x.getDb(SCApp.daoConfig).update(DayData.class, WhereBuilder.b("date", "=", dayData.getDate()), new KeyValue("calConsume", energy), new KeyValue("steps", step));
//leakcanary
                //i("@@@", "DataSizeB" + x.getDb(SCApp.daoConfig).selector(DayData.class).findAll().size());
            } catch (DbException e) {
                e.printStackTrace();
            }
        }


    }


    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }


}
